package com.futvan.z.framework.core;

import java.io.PrintWriter;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.core.MethodParameter;
import org.springframework.core.NamedThreadLocal;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSONObject;
import com.futvan.z.framework.common.bean.Result;
import com.futvan.z.system.zorg.z_org;
import com.futvan.z.system.zuser.z_user;
import com.futvan.z.framework.util.DateUtil;
import com.futvan.z.framework.util.JsonUtil;
import com.futvan.z.framework.util.SystemUtil;
import com.futvan.z.system.zlog.z_log;

public class AllHandlerInterceptor extends SuperZ implements HandlerInterceptor {

	private static final ThreadLocal<Long> startTimeThreadLocal =  new NamedThreadLocal<Long>("ThreadLocal StartTime");  
	/** 
	 * Handler执行之前调用这个方法 (1)
	 */
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {
		//设置请求开始时间，供afterCompletion方法计算请求周期总耗时
		startTimeThreadLocal.set(System.currentTimeMillis());
		//获取请求方法所有包路径，并判读是否验证登陆状态
		if(handler instanceof HandlerMethod) {
			HandlerMethod method= ((HandlerMethod)handler);
			String pageage = method.getBeanType().getTypeName();
			if(pageage.indexOf("com.futvan.z.framework")>=0 || pageage.indexOf("com.futvan.z.system")>=0) {

				String methodName = method.getMethod().getName();//获取方法名
				if("login".equals(methodName) 
						|| "error_404".equals(methodName) 
						|| "send_vcode".equals(methodName)
						|| "httpservices".equals(methodName)
						|| "upload".equals(methodName)
						|| "deleteServerFile".equals(methodName)
						|| "getUserOrgForUserId".equals(methodName) 
						|| "getMenuList1ForWX".equals(methodName) 
						|| "LoadParameter".equals(methodName) 
						|| "default_index".equals(methodName) 
						|| "getNewZ".equals(methodName) 
						|| "UserLogin".equals(methodName)
						|| "UserLoginJson".equals(methodName)) {
					//当前方法不需要判读登陆状态
					return true;
				}else {
					//判读是否登陆
					if(z.isNotNull(GetSessionUserId(request))) {

						//刷新当前Session中的用户列表
						RefreshSessionUser(request);

						return true;
					}else {
						response.sendRedirect("login");
						return false;
					}
				}
			}else {
				return true;
			}
		}else {
			return true;
		}

	}

	/**
	 * Handler执行之后，ModelAndView返回之前调用这个方法 (2)
	 */
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,ModelAndView modelAndView) throws Exception {
		if(handler instanceof HandlerMethod) {
			long beginTime = startTimeThreadLocal.get();//得到线程绑定的局部变量（开始时间）    
			long endTime = System.currentTimeMillis();  //2、结束时间    
			if(handler instanceof HandlerMethod) {

				if("true".equals(z.sp.get("isPrintLog"))) {
					HandlerMethod method= ((HandlerMethod)handler);
					BigDecimal times = (new BigDecimal(endTime).subtract(new BigDecimal(beginTime))).divide(new BigDecimal(1000),4, BigDecimal.ROUND_DOWN);
					String loginfo = "[请求方法]:"+method.getMethod().getName()+"|[耗时]:"+times;
					//获取参数
					String parameters = "";
					if(z.isNotNull(request) && request.getParameterMap().size()>0) {
						parameters = " | 参数："+JsonUtil.getJson(request.getParameterMap());
						loginfo = loginfo + parameters;
					}
					z.Log(loginfo);
				}



			}

			HttpSession session = null;
			try {
				session = request.getSession();
			} catch (Exception e) {}

			if(z.isNotNull(session)) {
				z_log log = new z_log();
				log.setLogtype("http_log");
				log.setSessionid(session.getId());

				Object user_obj = session.getAttribute("zuser");
				if(user_obj!=null && user_obj instanceof z_user) {
					z_user user = (z_user) user_obj;
					log.setUserid(user.getZid());
				}

				Object org_obj = session.getAttribute("zorg");
				if(org_obj!=null && org_obj instanceof z_org) {
					z_org org = (z_org) org_obj;
					log.setUserorgid(org.getZid());
				}
				log.setCustomIP(request.getRemoteAddr());
				log.setServerIP(request.getLocalAddr());
				HandlerMethod method= ((HandlerMethod)handler);
				log.setPackagepath(method.getBeanType().getTypeName());
				log.setFunctionname(method.getMethod().getName());
				log.setParameter(JSONObject.toJSONString(request.getParameterMap()));
				BigDecimal times = (new BigDecimal(endTime).subtract(new BigDecimal(beginTime))).divide(new BigDecimal(1000),4, BigDecimal.ROUND_DOWN);
				log.setRuntime(times.toString());
				SaveSystemLog(log);
			}
		}
	}

	/** 
	 * Handler执行完成之后调用这个方法 (3)
	 */ 
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)throws Exception {

	}

}
